#pragma once
#include <cstddef>
#include <iostream>
#include <ostream>
#include <string.h>
#include <assert.h>

using std::cout; 
using std::endl;

namespace real
{
    class string
    {
    private:
        // 给个默认值, 现代写法构造函数交换后出作用域析构对空指针不会出错, 野指针会
        char* _str = nullptr;
        size_t _size = 0;
        size_t _capacity = 0;

    public:
        typedef char* iterator;
        typedef const char* const_iterator;
        // static const 只有整数家族支持这样写:
        static const size_t npos = -1;

        // struct func
        string()
        :_str(new char[1]{'\0'})
        ,_size(0)
        ,_capacity(0)
        {
        }

        string(const char* ch)
        {
            _size = strlen(ch);
            _capacity = _size;
            _str = new char[_capacity+1];
            strcpy(_str, ch);
        }

        // copy struct func
        // string(const string& s)
        // {
        //     _capacity=s._capacity;
        //     _size=s._size;
        //     _str = new char[_capacity+1];
        //     strcpy(_str, s._str);
        // }

        // 现代写法
        string(const string& s)
        {
            string tmp(s._str);
            swap(tmp);
        }

        // destory func
        ~string()
        {
            cout << "~string(): " << endl;
            if(_str){
                delete[] _str;
                _str = nullptr;
                _size = 0;
                _capacity = 0;
            }
        }

        void clear()
        {
            _str[0] = '\0';
            _size = 0;
        }

        char* c_str() const
        {
            return _str;
        }

        char& operator[](size_t pos)
		{
			assert(pos < _size);

			return _str[pos];
		}

		const char& operator[](size_t pos) const
		{
			assert(pos < _size);

			return _str[pos];
		}

        iterator begin()
        {
            return _str;
        }

        iterator end() 
        {
            return _str+_size;
        }
        const_iterator begin() const
        {
            return _str;
        }

        const_iterator end() const
        {
            return _str+_size;
        }

        size_t size() const
        {
            return _size;
        }

        size_t capacity() const
        {
            return _capacity;
        }

        void swap(string& s)
        {
            std::swap(_str, s._str);
            std::swap(_size, s._size);
            std::swap(_capacity, s._capacity);
        }

        void reserve(size_t size);
        void push_back(char c);
        void append(const char* str);
        string& insert(size_t pos, const char c);
        string& insert(size_t pos, const char* str);
        string& erase(size_t pos, size_t len=npos);

        // string& operator=(const string& s);
        
        // 现代写法2
        string& operator=(string s);
        string operator+(const string& s) const;
        string& operator+=(const string& s);
        bool operator>(const string& s) const;
        bool operator>=(const string& s) const;
        bool operator<(const string& s) const;
        bool operator<=(const string& s) const;
        bool operator==(const string& s) const;
        bool operator!=(const string& s) const;
    };
};

std::ostream& operator<<(std::ostream& out, const real::string& s);